import { ElMessage, ElLoading } from 'element-plus'
import type { LoadingInstance } from 'element-plus'
import type { ApiResponse } from '~/types/api'
import { useAppStore } from '~/stores/app'

interface RequestOptions {
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
  data?: any
  headers?: Record<string, string>
  showLoading?: boolean
  type?: 'formData' | 'json'
  isSha256?: boolean
}

class HttpService {
  private baseURL: string = ''
  private loadingInstance: LoadingInstance | null = null

  constructor(baseURL: string) {
    this.baseURL = baseURL
  }

  async request<T>(url: string, options: RequestOptions = {}): Promise<ApiResponse<T>> {
    const {
      method = 'GET',
      data,
      headers = {},
      showLoading = true
    } = options
    
    // 根据不同请求指定header的Content-Type
    if (options.type === 'formData') {
      headers['Content-Type'] = 'application/x-www-form-urlencoded'
    } else {
      headers['Content-Type'] = 'application/json;charset=UTF-8'
    }
    
    if (options.isSha256) {
      headers['Content-SHA-256'] = 'true'
    }
    
    const noTokenUrlList = [
      '/oauth2/password'
    ]
    
    const checkUrlToken = (url: string) => {
      return noTokenUrlList.some(item => url.indexOf(item) > -1)
    }
    
    // 获取token（在客户端环境中）
    if (process.client) {
      try {
        const appStore = useAppStore()
        const token = appStore.token
        if (token && token.jwt_token) {
          let ret = checkUrlToken(url)
          headers['jwt-token'] = ret ? '' : token.jwt_token
        }
      } catch (error) {
        // 忽略 store 未初始化的情况
        console.warn('Store not available:', error)
      }
    }
    
    // 显示加载状态
    if (showLoading && process.client) {
      this.loadingInstance = ElLoading.service({
        lock: true,
        text: '加载中...',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    }

    try {
      const config: RequestInit = {
        method,
        headers: {
          'Content-Type': 'application/json',
          ...headers
        }
      }

      if (data && method !== 'GET') {
        config.body = JSON.stringify(data)
      }

      const response = await fetch(`${url}`, config)

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      const result: ApiResponse<T> = await response.json()

      // 根据业务逻辑处理响应
      if (result.code === '-1') {
        throw new Error(result.message || '请求失败')
      }

      return result
    } catch (error) {
      console.error('Request failed:', error)
      if (process.client) {
        ElMessage.error(error instanceof Error ? error.message : '请求失败')
      }
      throw error
    } finally {
      // 关闭加载状态
      if (this.loadingInstance && process.client) {
        this.loadingInstance.close()
        this.loadingInstance = null
      }
    }
  }

  async get<T>(url: string, params?: any, options: Omit<RequestOptions, 'method' | 'data'> = {}): Promise<ApiResponse<T>> {
    const queryString = params ? `?${new URLSearchParams(params).toString()}` : ''
    return this.request<T>(`${url}${queryString}`, { method: 'GET', ...options })
  }

  async post<T>(url: string, data?: any, options: Omit<RequestOptions, 'method'> = {}): Promise<ApiResponse<T>> {
    return this.request<T>(url, { method: 'POST', data, ...options })
  }

  async put<T>(url: string, data?: any, options: Omit<RequestOptions, 'method'> = {}): Promise<ApiResponse<T>> {
    return this.request<T>(url, { method: 'PUT', data, ...options })
  }

  async delete<T>(url: string, options: Omit<RequestOptions, 'method'> = {}): Promise<ApiResponse<T>> {
    return this.request<T>(url, { method: 'DELETE', ...options })
  }
}

// 创建HTTP服务实例
export const createHttpService = (baseURL: string) => new HttpService(baseURL)

// 兼容原有接口
export const request = <T>(url: string, isLoading?: boolean, options: any = {}): Promise<ApiResponse<T>> => {
  const config = useRuntimeConfig()
  const httpService = createHttpService(config.public.apiBase)
  return httpService.request<T>(url, {
    method: options.method?.toUpperCase() as 'GET' | 'POST' | 'PUT' | 'DELETE',
    data: options.data,
    headers: options.headers,
    showLoading: isLoading
  })
}

export default request
